package cn.sytton.taffe.framework.validation;

import cn.hutool.core.util.StrUtil;
import cn.sytton.taffe.framework.base.mapper.BaseMapper;
import cn.sytton.taffe.framework.exception.BizException;
import cn.sytton.taffe.framework.util.JsonUtil;
import cn.sytton.taffe.framework.util.SpringContextUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 重复数据验证器
 *
 * @author skyrock
 */
public class ValidatorDuplicate implements ConstraintValidator<NotDuplicate, Object> {

    private Field[] fields;
    private String mapperName;
    private String parentExcludeByField;

    @Override
    public void initialize(NotDuplicate constraintAnnotation) {
        fields = constraintAnnotation.value();
        mapperName = constraintAnnotation.mapperName();
        parentExcludeByField = constraintAnnotation.excludeByField();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if (!StringUtils.hasText(mapperName)) {
            String className = o.getClass().getSimpleName();
            String mapper = o.getClass().getSimpleName().substring(0, className.length() - 6); //取掉"Entity"
            mapperName = StrUtil.lowerFirst(mapper)+"Mapper";
        }
        return validate(o);
    }


    public boolean validate(Object o) {
        Map<String, Object> validData = JsonUtil.getEntity(JsonUtil.getString(o));
        for(Field f : fields) {
            boolean isNullValue = false;
            List<String> values = new ArrayList<>();
            QueryWrapper<?> sectionQueryWrapper = new QueryWrapper<>();
            for(String name : f.name()) {
                Object value = validData.get(name);
                if (ObjectUtils.isEmpty(value)) {
                    isNullValue = true;
                    break;
                } else {
                    values.add(value.toString());
                    sectionQueryWrapper.eq(name, value);
                }
            }
            if (isNullValue) {
                //如果遇到空值，跳过当前field校验
                continue;
            }

            String excludeByField = getExcludeFiled(parentExcludeByField, f.excludeByField());
            if (StringUtils.hasText(excludeByField) && validData.get(excludeByField) != null) {
                sectionQueryWrapper.ne(excludeByField ,validData.get(excludeByField));
            }

            Object instance = SpringContextUtil.getBean(mapperName);
            long count = ((BaseMapper)instance).selectCount(sectionQueryWrapper);
            if (count > 0) {
                throw new BizException(String.format(f.message(), (Object[]) values.toArray(new String[0])));
            }
        }
        return true;
    }

    private String getExcludeFiled(String parentExcludeField, String childExcludeField ) {
        if (StringUtils.hasText(childExcludeField)) {
            return childExcludeField;
        } else if (StringUtils.hasText(parentExcludeField)) {
            return parentExcludeField;
        } else {
            return "";
        }
    }
}
